Examples - Sample Applications
Sample Applications
PVA ISP provides four C++ example applications. Built-from-source binaries are shown below as ./builddir/out/bin/...; use the corresponding installed path in an evaluation package. All examples require an even image resolution and a YAML parameter file. RAW input is stored in 16-bit samples, with the meaningful sample depth and Bayer pattern described by the configuration. Match both to the actual sensor data before evaluating image quality.
| Application | What it demonstrates | Output |
|---|---|---|
isp_minimal
|
One RAW file through separate or joined ISP stages, with optional convolution, BLC, and DLUT tone mapping. | One NV12 file, default <image>.nv12.
|
isp_minimal_cuda
|
CUDA-mapped input/output boundary buffers rotated between PVA executions. | One NV12 file containing the final iteration. |
isp_multicamera
|
2–16 simulated cameras, each with an independent joined DLUT pipeline and execution session. | One NV12 file per simulated camera. |
isp_app
|
File input or V4L2 capture, histogram and Auto Exposure branches, optional CSV exports and PVA statistics. | File mode writes <image>.out; capture mode processes frames without writing an NV12 file.
|
All four examples load examples/configs/params.yaml. The example parameter file is included below. Its decompand.x_pts are compressed input codes and decompand.y_pts are linear 16-bit output codes. The gamma_tone_mapping.lut entries are ignored while build_lut: true. Camera calibration values should be adjusted for the actual sensor.
Example: examples/configs/params.yaml
# yaml-language-server: $schema=./params.schema.yaml
# Copyright (C) 2026 RidgeRun, LLC (http://www.ridgerun.com)
# All Rights Reserved.
#
# The contents of this software are proprietary and confidential to RidgeRun,
# LLC. No part of this program may be photocopied, reproduced or translated
# into another programming language without prior written consent of
# RidgeRun, LLC. The user is free to modify the source code after obtaining
# a software license from RidgeRun. All source code changes must be provided
# back to RidgeRun without any encumbrance.
# Reference parameter file for the ISP examples.
# This sample matches `params.schema.yaml` and the runtime loader used by:
# - isp_minimal
# - isp_minimal_cuda
# - isp_multicamera
# - isp_app
decompand:
input_shift: 4
x_pts: [0, 1098, 1885, 2501, 3062, 3602, 3914, 3975, 4095]
y_pts: [0, 1107, 3325, 7766, 16652, 34430, 52207, 56648, 65535]
convolution:
kernel: [1, 2, 1, 2, 4, 2, 1, 2, 1]
shift: 4
color_correction:
matrix: [1, 0, 0, 0, 1, 0, 0, 0, 1]
shift: 0
black_level:
channel00: 16
channel01: 16
channel10: 16
channel11: 16
digital_gain:
channel_gains: [1.5, 1.5, 1.5, 1.5]
white_balance:
u_ref: [0.982, 0.789, 0.668, 0.558, 0.426]
v_ref: [0.308, 0.382, 0.445, 0.428, 0.678]
use_calibration: false
manual_wb: false
manual_wb_gains: [1.0, 1.0, 1.0]
demosaic:
bayer_pattern: 0
histogram:
bit_depth: 16
use_mask: false
auto_exposure:
kp_exposure: 40.0
ki_exposure: 1.0
kd_exposure: 8.0
kp_gain: 5000000.0
ki_gain: 10.0
kd_gain: 500.0
reference_mean: 120.0
dynamic_range: 255.0
min_exposure: 5000
max_exposure: 20000
min_gain: 2000000
max_gain: 100000000
camera_index: 0
enable_v4l2: false
gamma_tone_mapping:
build_lut: true
gamma: 2.2
lut: [
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143,
144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159,
160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175,
176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191,
192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207,
208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223,
224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239,
240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255
]
global_tone_mapping:
brightness: 0.18
gtm_scale_min: 0.0001
gtm_scale_max: 0.01
gtm_temporal_alpha: 1.0
debug:
export_scene_key: false
export_debug_csv: false
debug_export_frame_index: 0
isp_minimal
isp_minimal loads one RAW image, executes the selected graph repeatedly, and writes only the final NV12 result. --num-frames defaults to 100 processing iterations. It does not read a sequence of different source frames.
Usage
./builddir/out/bin/isp_minimal --image <raw-file> --resolution <width>x<height> \ --parameters <yaml> [--output <nv12-file>] [--dump-graph <dot-file>] \ [--num-frames <iterations>] [--no-convolution] [--disable-blc] \ [--join-kernels] [--gtm-dlut] [--stats]
--no-convolutionskips the spatial filter but keeps Color Correction.--disable-blcuses White Balance Gains in place of Black Level Correction.--join-kernelsselects Input Stage, Pre RGB, combined Convolution + Color Correction when convolution is enabled, and Post RGB. Without convolution it retains standalone Color Correction.--gtm-dlutselects standalone DLUT Global Tone Mapping or, with--join-kernels, Post RGB DLUT.--statsprints per-stage PVA execution statistics.--dump-graphwrites Graphviz DOT after preparation.
The standard graph is Decompand → Black Level / WB Gains → White Balance → Demosaic → [Convolution] → Color Correction → Global Tone Mapping → Gamma → NV12 Conversion. The joined graph is Input Stage → Pre RGB → [Convolution + Color Correction / Color Correction] → Post RGB. The selected tone-mapping path changes the relevant final stage. A scene-key side connection feeds tone mapping in either graph.
File example
./builddir/out/bin/isp_minimal \ --image input.raw \ --resolution 1920x1080 \ --parameters examples/configs/params.yaml \ --output /tmp/input.nv12 \ --num-frames 1
Use the IMX274 reference RAW file or another compatible RAW input. Use its actual resolution, Bayer pattern, and alignment when running the example. The command as written expects a 1920×1080×2-byte RAW16 file, with the Bayer pattern and low-bit alignment specified by the YAML. For another image, change the resolution and sensor parameters accordingly. NV12 has one full-resolution Y plane plus a half-height interleaved UV plane; view it using the input width and height, rather than the storage height H + H/2.
The following image shows an example output. It is illustrative; it is not a validation target for arbitrary input RAW data.
A successful run prepares the selected stages, prints initialization and average execution times, and writes the requested NV12 file. Logger details and timing values vary by graph, hardware, and run. Check the log for the selected stages, completed processing, and the output path.
isp_minimal_cuda
isp_minimal_cuda is built when the CUDA Toolkit is available. Its fixed joined graph is Input Stage → Pre RGB → Color Correction → Post RGB DLUT. It creates a pool of CUDA-mapped Bayer input and NV12 output buffer pairs and uses Pipeline::updateExternalFrame() between iterations to rotate those external boundary allocations. It writes only the final NV12 result.
./builddir/out/bin/isp_minimal_cuda --image <raw-file> \ --resolution <width>x<height> --parameters <yaml> \ [--output <nv12-file>] [--dump-graph <dot-file>] \ [--num-frames <iterations>] [--num-buffers <count>] [--stats]
--num-frames defaults to 100; --num-buffers defaults to 2. The input and output frame specifications stay fixed while the underlying CUDA pointers change. The external allocations must remain valid for each process() call. See Custom Application Development for the boundary-frame API.
isp_multicamera
isp_multicamera simulates cameras by copying the same loaded RAW16 frame into 2–14 independent pipelines. It does not capture from multiple physical cameras. Each pipeline runs Input Stage → Pre RGB → Post RGB DLUT; Convolution and Color Correction are omitted. Cameras run in sequential batches of two, with the pair submitted concurrently on separate execution sessions and streams.
./builddir/out/bin/isp_multicamera --image <raw-file> \ --resolution <width>x<height> --parameters <yaml> \ [--output-prefix <prefix>] [--dump-graph <dot-file>] \ [--num-frames <iterations>] [--num-cameras <2-16>] [--stats]
--num-cameras defaults to 2; --num-frames defaults to 100 per camera. The output prefix defaults to the input path, producing <prefix>_camera0.nv12, <prefix>_camera1.nv12, and so on. The graph export describes one representative camera because their topologies are identical. The average execution time reports a complete all-camera round, excluding initialization and file I/O.
isp_app
isp_app is the full example. Its separate graph includes Decompand, Black Level Correction, White Balance, Demosaic, Convolution, Color Correction, Global Tone Mapping, Gamma Tone Mapping, and NV12 Conversion. A Histogram → Auto Exposure branch consumes corrected Bayer data. --join-kernels replaces the image path with Input Stage, Pre RGB, Convolution + Color Correction, and Post RGB while retaining Histogram and Auto Exposure. isp_app does not have a --gtm-dlut option.
Usage
./builddir/out/bin/isp_app (--image <raw-file> | --device /dev/videoN) \ --resolution <width>x<height> --parameters <yaml> \ [--num-frames <count>] [--format <0|1|2>] [--mask <mask-file>] \ [--dump-graph <dot-file>] [--gtm-luminances-csv <path>] \ [--gtm-scene-key-csv <path>] [--join-kernels] [--stats]
The capture format numbers are 0 = BG12 (BGGR), 1 = RG10 (RGGB), and 2 = BYR2 (BGGR). The format matters for V4L2 input and must match demosaic.bayer_pattern in the YAML. --mask supplies a float histogram mask. The GTM CSV path options override the default locations under debug/. Debug export settings are in the YAML debug section. CSV exporters require separate stages: isp_app --join-kernels rejects debug.export_debug_csv: true or debug.export_scene_key: true. --stats and graph export still work with joined kernels.
File input example
./builddir/out/bin/isp_app \ --image input.raw \ --resolution 1920x1080 \ --parameters examples/configs/params.yaml \ --num-frames 1
A one-frame RAW16 file can be reused for the requested frame count, or the file may contain exactly that many concatenated frames. File mode writes input.raw.out (one NV12 frame per processed input) and computes Auto Exposure controls without writing them to a camera. The YAML sample's debug_export_frame_index must be below --num-frames when CSV export is enabled.
V4L2 input example
./builddir/out/bin/isp_app \ --device /dev/video0 \ --resolution 1920x1080 \ --format 0 \ --parameters examples/configs/params.yaml \ --num-frames 100
The sample YAML selects Bayer pattern 0 (BGGR), matching capture format 0. Capture mode writes computed exposure and gain through V4L2 controls and requires a suitable /dev/videoN device. It processes the requested captured frames and does not write an NV12 output file. Applications that need to save or stream captured NV12 data should consume the pipeline output in their own loop.
Source Code Guide
The example application sources are examples/isp_minimal.cpp, examples/isp_minimal_cuda.cpp, examples/isp_multicamera.cpp, and examples/isp_full_application.cpp (isp_app). Shared helpers are in examples/isp_example_common.cpp; YAML loading is in examples/isp_params/isp_params.cpp. The full applications use the public Pipeline API described in Custom Application Development.
How isp_minimal runs
parseArgs()validates input, resolution, parameter path, and graph switches.loadIspParams()parses the YAML parameter file.buildStandardPipeline()orbuildJoinedPipeline()creates stages withaddStage(), links the main image path and the requiredgainsandscene_keypads, and sets stage properties.bindBoundaryFrames()binds Bayer input and NV12 output throughsetInput()andsetOutput(), using the configured Bayer pattern and an NV12 storage height ofH + H/2.prepare(options.stats)initializes, negotiates, allocates, and configures the pipeline. The optional Graphviz graph is then written.- The application loads the RAW16 file, copies it into the input frame's host mapping, calls
process()for the requested iterations, reports average time, and writes the final NV12 buffer.
The YAML parser uses names such as params.decompand.inputShift, params.decompand.xPts, and params.decompand.yPts internally. The public stage property for input alignment is named shift_bits. Use examples/isp_minimal.cpp as the C++ reference for the complete stage configuration and graph.